package com.ayg.service;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.ayg.mapper.UserMapper;
import com.ayg.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MailService mailService;

    /**
     * 注册账户
     *
     * @param user
     * @return
     */
    @Override
    @Transactional
    public String createAccount(User user) {
        //通过email查询数据库里用户对应的记录 如果存在返回用户已存在
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(null);
        userQueryWrapper.eq("email", user.getEmail());
        //判断数据库是否有此邮箱，没有则进行注册
        if (userMapper.selectCount(userQueryWrapper) > 0) {
            QueryWrapper<User> userQueryWrapper1 = new QueryWrapper<>(null);
            userQueryWrapper.eq("email", user.getEmail());
            User user2 = userMapper.selectOne(userQueryWrapper);
            if (user2.getIsValid()!=0) {
                String StatusCode201 = "2001";
                return StatusCode201; //返回：该用户已存在
            } else {
                String StatusCode202 = "2002";
                return StatusCode202; //返回：该账户已存在，请前往邮箱激活!
            }
        }
        // 雪花算法生成确认码
        String confirmCode = IdUtil.getSnowflake(1, 1).nextIdStr();
        //盐
        String salt = RandomUtil.randomString(6);
        //加密密码 ：原始密码 + 盐
        String md5Pwd = SecureUtil.md5(user.getPassword() + salt);
        //激活失效时间： 24小时
        LocalDateTime localDateTime = LocalDateTime.now().plusDays(1);
        //初始化账号信息
        user.setSalt(salt);
        user.setPassword(md5Pwd);
        user.setConfirmCode(confirmCode);
        user.setActivationTime(localDateTime);
        user.setIsValid((byte) 0);//设定默认值为 0 账号不可用状态
        //新增账号
        int result = userMapper.insert(user);

        if (result > 0) {
            //发邮件
            /**
             * 这里需要注意不能将127.0.0.1改为localhost，否则点击邮箱中的地址会出现页面无法访问的情况
             */
            String activationUrl = "http://127.0.0.1:8099/user/activation?confirmCode=" + confirmCode;
            mailService.sendMailForActivationAccount(activationUrl, user.getEmail());

            String StatusCode204 = "2004";
            return StatusCode204; //返回：注册成功，请前往邮箱进行账号激活
        } else {
            String StatusCode205 = "2005";
            return StatusCode205; //返回：注册失败
        }


    }

    /**
     * 实现用户登录操作
     * 1.将明文转化为密文 MD5加密
     * 2.通过email和password查询数据库.
     * 3.
     *     有数据: 用户名和密码正确  返回UUID token
     *     没有数据: 用户名和密码错误 返回null
     * @param user
     * @return
     */
    @Override
    public String login(User user) {
        //通过email查询数据库里用户对应的记录
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("email",user.getEmail()).eq("is_valid",1);
        List<User> userList = userMapper.selectList(userQueryWrapper);

        //查询不到结果，返回null
        if (userList == null || userList.isEmpty()){
            String StatusCode206="2006";
            return StatusCode206;
        }
        //查询到多个用户，返回null
        if (userList.size() > 1){
            String StatusCode203="2003";
            return StatusCode203;
        }
        //查询到一个用户，进行密码比对
        User aUser = userList.get(0);
        //用户输入的的密码和盐进行加密
        String md5Pwd = SecureUtil.md5(user.getPassword() + aUser.getSalt());
        //密码不一致，返回:用户名或者密码错误
        if (!aUser.getPassword().equals(md5Pwd)){
            String StatusCode207="2007";
            return StatusCode207;
        }else {
            //以上判断条件不满足，则返回token密钥
            String token = UUID.randomUUID().toString().replace("-", "");
            //controller层返回 StatusCode208
            return token;
        }
    }

    /**
     * 账号激活
     * @param confirmCode
     * @return
     */

    @Override
    @Transactional
    public String activationAccount(String confirmCode) {
        //根据确认码查询用户
        QueryWrapper<User> activationQueryWrapper = new QueryWrapper<>();
        activationQueryWrapper.eq("confirm_code",confirmCode);
        User user = userMapper.selectOne(activationQueryWrapper);
        //激活失效时间： 24小时
        LocalDateTime localDateTime = LocalDateTime.now().plusDays(1);
        //初始化账号信息
        user.setActivationTime(localDateTime);
        //判断激活时间是否超时
        boolean after = LocalDateTime.now().isAfter(user.getActivationTime());
        if(after){
            String StatusCode209="2009";//链接已失效！请重新注册
            return StatusCode209;
        }else {
            //根据确认码查询用户并修改状态值为 1 （可用）
            user.setIsValid((byte) 1);
            UpdateWrapper updateWrapper = new UpdateWrapper();
            updateWrapper.eq("is_valid",0);
            int updateConfirmCode = userMapper.update(user, updateWrapper);
            String StatusCode210;
            String StatusCode211;
            if (updateConfirmCode > 0) {
                StatusCode210 = "2010";//激活成功！
                return StatusCode210;
            } else {
                StatusCode211 = "2011";//激活失败！
                return StatusCode211;
            }
        }
    }

    /**
     * 找回密码
     * @param user
     * @return
     */
    @Override
    public String updatePass(User user) {
        //用户输入的的密码和盐进行加密
        String updatePassword=user.getPassword();

        //通过email phone查询数据库里用户对应的记录
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(null);
        userQueryWrapper.eq("email", user.getEmail()).eq("phone", user.getPhone());
        List<User> selectList = userMapper.selectList(userQueryWrapper);

        if (selectList.size()==1){
            //发邮件
            /**
             * 这里需要注意不能将127.0.0.1改为localhost，否则点击邮箱中的地址会出现页面无法访问的情况
             */
            String activationPassUrl = "http://127.0.0.1:8099/user/activationPass?userEmail=" +user.getEmail()+"&userPassword="+updatePassword;
            mailService.sendMailForActivationPassAccount(activationPassUrl,user.getEmail());

            String StatusCode212 = "2012";
            return StatusCode212; //返回：请前往邮箱进行重置确认！
        } else {
            String StatusCode213 = "2013";
            return StatusCode213; //返回：重置失败
        }

    }

    /**
     * 找回密码--重置密码
     * @param userEmail
     * @param userPassword
     * @return
     */
    @Override
    @Transactional //事物回滚
    public String activationPass(String userEmail,String userPassword) {
        System.out.println(userEmail);
        System.out.println(userPassword);
        //根据确认码查询用户
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("email", userEmail);
        User user = userMapper.selectOne(userQueryWrapper);
        String oldPassword = user.getPassword();
        String oldSalt=user.getSalt();
        String md5Pwd = SecureUtil.md5(userPassword+oldSalt);


        //根据邮箱查询用户并修改密码为userPassword
        User setPassword = user.setPassword(md5Pwd);
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("password",oldPassword);
        int update = userMapper.update(setPassword,updateWrapper);
        String StatusCode214;
        String StatusCode212;
        if (update > 0) {
            StatusCode214 = "2014";//重置成功！
            return StatusCode214;
        } else {
            StatusCode212 = "2012";//重置失败！
            return StatusCode212;
        }
    }
}





